package silo.dungeonbuddy;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.io.File;
import java.util.Vector;

public class ToolBox extends Form
{
	private boolean dragging=false;
	private int dragOffsetX=0;
	private int dragOffsetY=0;
	private FormImage draggedImage;
	private Terrain draggedTerrain;
	private Unit draggedUnit;
	private Marker draggedMarker;
	private Effect draggedEffect;
	private Object draggedObject;
	private IntValue offset = new IntValue(0);
	private long lastUpdate = System.currentTimeMillis();
	private long mouseUpdateTime=System.currentTimeMillis();
	
	public ToolBox(String eName, Start eGame, int eX, int eY, int eWidth, int eHeight, String eTitle)
	{
		super(eName, eGame, eX, eY, eWidth, eHeight, eTitle);
		//File dir = new File("./terrain/");
		populateContents();
		if(((images.size()/5)*30)>300)
		{
			scrollBars.add(new ScrollBar(width-20,0,20,height,true,offset,(((images.size()/5)*30)-300)));
		}else
		{
			scrollBars.add(new ScrollBar(width-20,0,20,height,true,offset,((images.size()/7)*30)));
		}
		draggedImage=null;
		dragging=false;
	}//constructor
	
	public void draw()
	{
		// GET CONTEXT FOR ACCELERATED GRAPHICS
		Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
		g.setColor(Color.gray);
		g.fillRect(0,0,width,height);
		//g.setColor(Color.black);
		//g.fillRect(0,0,width,20);
		if(scrollBars.size()>0)
		{
			for(int i=0;i<scrollBars.size();i++)
			{
				ScrollBar s = (ScrollBar)scrollBars.get(i);
				s.draw(g);
			}//next i
		}//if(scrollBars.size()>0)
		if(textBoxes.size()>0)
		{
			for(int i=0;i<textBoxes.size();i++)
			{
				TextBox t = (TextBox)textBoxes.get(i);
				t.draw(g);
			}//next i
		}//if(textBoxes.size()>0)
		if(buttons.size()>0)
		{
			for(int i=0;i<buttons.size();i++)
			{
				Button b = (Button)buttons.get(i);
				b.draw(g);
			}//next i
		}//if(buttons.size()>0)
		if(labels.size()>0)
		{
			for(int i=0;i<labels.size();i++)
			{
				Label l = (Label)labels.get(i);
				l.draw(g,l.getX(),l.getY()+offset.getValue());
			}//next i
		}//if(labels.size()>0)
		if(images.size()>0)
		{
			for(int i=0;i<images.size();i++)
			{
				FlatImage f = (FlatImage)images.get(i);
				f.draw(g,f.getX(),f.getY()+offset.getValue());
			}//next i
		}//if(images.size()>0)
		if(draggedImage!=null)
		{
			draggedImage.draw(g);
		}
		
		//DISPOSE OF GRAPHICS OBJECT AND FLIP BUFFER
		g.dispose();
		strategy.show();
	}//draw
	
	public void function(Graphics2D g)
	{
		if (isFocusOwner())
		{
			// For now, focus is not an issue, since the last window will have focus
			// until it is closed. - that's not true.  I don't know why I put that comment in...
			// oh, I meant that the focus variable was never being set to false.  I WAS using
			// a boolean variable to keep track of focus, but decided that was stupid...
			checkScrollBars();
			checkButtons(g);
			checkTextBoxes();
			checkKeys();
			checkMouse();
			/*if((System.currentTimeMillis() - lastUpdate) > 1000)
			{
				//TODO: Need to fix this because it is slow, and will get slower as more items are added.
				updateContents();
				lastUpdate = System.currentTimeMillis();
			}*/
		}else if(dragging)
		{
			checkMouse();
		}
	}//function
	
	public void checkMouse()
	{
		if(((System.currentTimeMillis()-mouseUpdateTime)>100)&&(isFocusOwner()))
		{
			mouseX = MouseInfo.getPointerInfo().getLocation().x-getLocationOnScreen().x;
			mouseY = MouseInfo.getPointerInfo().getLocation().y-getLocationOnScreen().y;
			mouseUpdateTime=System.currentTimeMillis();
		}//if((System.currentTimeMillis()-mouseUpdateTime)>100)
		if(!scrolling)
		{
			if((mouseLeft)&&((System.currentTimeMillis()-clickTime)>10)&&(!dragging))
			{
				dragging=true;
				for(int i=0;i<images.size();i++)
				{
					FormImage im = (FormImage)images.get(i);
					if((mouseX>im.getX())&&(mouseX<(im.getX()+im.getSizeX()))&&(mouseY>(im.getY()+offset.getValue()))&&(mouseY<(im.getY()+im.getSizeY()+offset.getValue())))
					{
						draggedImage=new FormImage(im.getName(), im.getRef(), game, im.getX(),im.getY(), im.getSizeX(), im.getSizeY());
						draggedImage.setOnBoard(false);
						dragOffsetX=mouseX-im.getX();
						dragOffsetY=mouseY-im.getY()-offset.getValue();
						i=images.size();
						break;
					}
				}//next i
				if(draggedImage==null)
				{
					dragging = false;
				}//if(draggedImage==null)
			}//if((mouseLeft)&&((System.currentTimeMillis()-clickTime)>600)&&(!dragging))
			if((!mouseLeft)&&(dragging)&&(isFocusOwner()))
			{
				dragging=false;
				draggedImage=null;
				draggedTerrain=null;
				draggedUnit=null;
				draggedMarker=null;
				draggedEffect=null;
				draggedObject=null;
			}
			if((game.isFocusOwner())&&(!game.getMouseLeft())&&(dragging))
			{
				dragging=false;
				draggedImage=null;
				game.determineSelectedSquare();
				if((game.getSelectedSquare() != null)&&(draggedTerrain!=null))
				{
					draggedTerrain.moveTo(game.getSelectedSquare());
					game.setSelectedPiece(draggedTerrain);
				}else if((game.getSelectedSquare() != null)&&(draggedUnit!=null))
				{
					draggedUnit.moveTo(game.getSelectedSquare());
					game.setSelectedPiece(draggedUnit);
				}else if((game.getSelectedSquare() != null)&&(draggedMarker!=null))
				{
					draggedMarker.moveTo(game.getSelectedSquare());
					if(game.getSelectedSquare().getOccupees().size()>0)
					{
						for(int i=(game.getUnitList().size()-1);i>=0;i--)
						{
							if(game.getSelectedSquare().getOccupees().contains(game.getUnitList().get(i)))
							{
								try
								{
									Unit u = (Unit)game.getUnitList().get(i);
									draggedMarker.setUnit(u);
									u.getMarkers().add(draggedMarker);
								}catch(Exception e)
								{
									
								}//catch e
							}//if(game.getSelectedSquare().getOccupees().contains(game.getUnitList().get(i)))
						}//next i
					}
					game.setSelectedPiece(draggedMarker);
				}else if((game.getSelectedSquare() != null)&&(draggedEffect!=null))
				{
					draggedEffect.moveTo(game.getSelectedSquare());
					game.setSelectedPiece(draggedEffect);
				}else if((game.getSelectedSquare() != null)&&(draggedObject!=null))
				{
					draggedObject.moveTo(game.getSelectedSquare());
					game.setSelectedPiece(draggedObject);
				}
				draggedObject=null;
				draggedEffect=null;
				draggedMarker=null;
				draggedTerrain=null;
				draggedUnit=null;
				game.clearSelectedSquare();
			}
			if(dragging)
			{
				if(isFocusOwner())
				{
					mouseX = MouseInfo.getPointerInfo().getLocation().x-getLocationOnScreen().x;
					mouseY = MouseInfo.getPointerInfo().getLocation().y-getLocationOnScreen().y;
				}else if(game.isFocusOwner())
				{
					//TODO: Fix the problem where the new piece is not dropped on drag release in the
					//main map window - it only drops after a release and click. (also the item is not selected, but the square instead)
					game.setMouseX(MouseInfo.getPointerInfo().getLocation().x-game.getLocationOnScreen().x);
					game.setMouseY(MouseInfo.getPointerInfo().getLocation().y-game.getLocationOnScreen().y);
				}
				if((draggedImage!=null)&&(isFocusOwner()))
				{
					draggedImage.setX(mouseX-dragOffsetX);
					draggedImage.setY(mouseY-dragOffsetY);
				}else if((game.isFocusOwner())&&(draggedTerrain!=null))
				{
					//Be sure to do this set of checks before the mouseposition check that follows.
					game.determineSelectedSquare();
					if(game.getSelectedSquare() != null)
					{
						draggedTerrain.moveTo(game.getSelectedSquare());
					}
				}else if((game.isFocusOwner())&&(draggedUnit!=null))
				{
					game.determineSelectedSquare();
					if(game.getSelectedSquare() != null)
					{
						draggedUnit.moveTo(game.getSelectedSquare());
					}
				}else if((game.isFocusOwner())&&(draggedMarker!=null))
				{
					game.determineSelectedSquare();
					if(game.getSelectedSquare() != null)
					{
						draggedMarker.moveTo(game.getSelectedSquare());
					}
				}else if((game.isFocusOwner())&&(draggedEffect!=null))
				{
					game.determineSelectedSquare();
					if(game.getSelectedSquare() != null)
					{
						draggedEffect.moveTo(game.getSelectedSquare());
					}
				}else if((game.isFocusOwner())&&(draggedObject!=null))
				{
					game.determineSelectedSquare();
					if(game.getSelectedSquare() != null)
					{
						draggedObject.moveTo(game.getSelectedSquare());
					}
				}
				if((isFocusOwner())&&((mouseX>width)||(mouseX<0)||(mouseY>height)||(mouseY<0))&&(((mouseX+getLocationOnScreen().x)>game.getLocationOnScreen().x)&&((mouseX+getLocationOnScreen().x)<(game.getLocationOnScreen().x+game.getWidth()))&&((mouseY+getLocationOnScreen().y)>game.getLocationOnScreen().y)&&((mouseY+getLocationOnScreen().y)<(game.getLocationOnScreen().y+game.getHeight())))&&(draggedImage != null))
				{
					if(draggedImage.getName().contains(".terrain"))
					{
						File file = new File("./" + draggedImage.getName());
						InputMessage IM = new InputMessage(ReadWriteTextFile.getContents(file),game);
						String tRef = IM.getTerrainRef();
						String tName = IM.getTerrainName();
						int c = (int)Math.floor(((mouseX + getLocationOnScreen().x - game.getLocationOnScreen().x)-game.getOffsetX().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						int r = (int)Math.floor(((mouseY + getLocationOnScreen().y - game.getLocationOnScreen().y)-game.getOffsetY().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						int tRow = r;
						int tCol = c;
						int tSizeX = IM.getTerrainSizeX();
						int tSizeY = IM.getTerrainSizeY();
						int tHeight = IM.getTerrainHeight();
						boolean tObstruction = IM.getTerrainObstruction();
						game.addTerrain(new Terrain(tName, game,tRef, "Terrain", tRow, tCol, tSizeX, tSizeY, tHeight, tObstruction));
						draggedTerrain = (Terrain)game.getTerrainList().get(game.getTerrainList().size()-1);
					}else if(draggedImage.getName().contains(".unit"))
					{
						File file = new File("./" + draggedImage.getName());
						InputMessage IM = new InputMessage(ReadWriteTextFile.getContents(file),game);
						Unit u = IM.getBoardUnit(new IntValue(-1));
						int c = (int)Math.floor(((mouseX + getLocationOnScreen().x - game.getLocationOnScreen().x)-game.getOffsetX().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						int r = (int)Math.floor(((mouseY + getLocationOnScreen().y - game.getLocationOnScreen().y)-game.getOffsetY().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						Vector v = (Vector)game.getBoard().getSquareList().get(r);
						Square s = (Square)v.get(c);
						u.setX(s.getX());
						u.setY(s.getY());
						u.setRow(r);
						u.setColumn(c);
						game.addUnit(u);
						draggedUnit = (Unit)game.getUnitList().get(game.getUnitList().size()-1);
					}else if(draggedImage.getName().contains(".marker"))
					{
						File file = new File("./" + draggedImage.getName());
						InputMessage IM = new InputMessage(ReadWriteTextFile.getContents(file),game);
						String uRef = IM.getMarkerRef();
						String uName = IM.getMarkerName();
						int c = (int)Math.floor(((mouseX + getLocationOnScreen().x - game.getLocationOnScreen().x)-game.getOffsetX().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						int r = (int)Math.floor(((mouseY + getLocationOnScreen().y - game.getLocationOnScreen().y)-game.getOffsetY().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						int uRow = r;
						int uCol = c;
						game.addMarker(new Marker(uName,game,uRef,"marker",uRow,uCol,1,1));
						draggedMarker = (Marker)game.getMarkerList().get(game.getMarkerList().size()-1);
					}else if(draggedImage.getName().contains(".png"))
					{
						int c = (int)Math.floor(((mouseX + getLocationOnScreen().x - game.getLocationOnScreen().x)-game.getOffsetX().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						int r = (int)Math.floor(((mouseY + getLocationOnScreen().y - game.getLocationOnScreen().y)-game.getOffsetY().getValue())/(game.getHeight()/game.getSquaresPerScreen()));
						int uRow = r;
						int uCol = c;
						game.addUnit(new Unit("No name",game,draggedImage.getRef(),"No owner",uRow,uCol,1,1,0));
						draggedUnit = (Unit)game.getUnitList().get(game.getUnitList().size()-1);
					}else
					{
						
					}
					draggedImage=null;
					game.setMouseLeft(true);
					game.requestFocus();
				}
			}
		}
	}//checkMouse
	
	public void populateContents()
	{
		labels.clear();
		images.clear();
		File dir = new File("./terrain/");
		String[] children = dir.list();
		int h=0;
		int v=0;
		labels.add(new Label("lblTerrainPieces","Terrain pieces (Drag onto board) :",5,20,200,20,true));
		if (children == null)
		{
			// Either dir does not exist or is not a directory
		}else
		{
			for (int i=0; i<children.length; i++)
			{
				// Get filename of file or directory
				String filename = children[i];
				if(filename.contains(".terrain"))
				{
					String tName = "";
					int k = 0;
					while(k<filename.length())
					{
						tName = tName + filename.charAt(k);
						k=k+1;
					}//loop
					tName = "terrain/" + tName;
					//File file = new File("./terrain/" + filename);
					File file = new File("./terrain/" + filename);
					InputMessage IM = new InputMessage(ReadWriteTextFile.getContents(file),game);
					String ref = "";
					ref = IM.getTerrainRef();
					images.add(new FormImage(tName,ref,game,(30*h)+(10*(h+1)),(30*v)+(10*(v+1))+30,30,30));
					FormImage fi = (FormImage)images.get(images.size()-1);
					fi.setOnBoard(false);
					h=h+1;
					if(h>=7)
					{
						h=0;
						v=v+1;
					}
				}
			}//next i
		}
		
		//dir = new File("./units/");
		dir = new File("./units/");
		children = dir.list();
		if (children == null)
		{
			// Either dir does not exist or is not a directory
		}else
		{
			h=0;
			v=v+1;
			labels.add(new Label("lblUnitPieces","Unit pieces :",5,(30*v)+(10*(v+1))+30+20,200,20,true));
			v=v+1;
			for (int i=0; i<children.length; i++)
			{
				// Get filename of file or directory
				String filename = children[i];
				if(filename.contains(".unit"))
				{
					String uName = "";
					int k = 0;
					while(k<filename.length())
					{
						uName = uName + filename.charAt(k);
						k=k+1;
					}//loop
					uName = "units/" + uName;
					//File file = new File("./units/" + filename);
					File file = new File("./units/" + filename);
					InputMessage IM = new InputMessage(ReadWriteTextFile.getContents(file),game);
					String ref = "";
					ref = IM.getBoardUnit(new IntValue(-1)).getRef();
					images.add(new FormImage(uName,ref,game,(30*h)+(10*(h+1)),(30*v)+(10*(v+1))+30,30,30));
					FormImage fi = (FormImage)images.get(images.size()-1);
					fi.setOnBoard(false);
					h=h+1;
					if(h>=7)
					{
						h=0;
						v=v+1;
					}//if(h>=7)
				}//if(filename.contains(".unit"))
			}//next i
		}//else -- (children == null)
		
		dir = new File("./markers/");
		children = dir.list();
		if (children == null)
		{
			// Either dir does not exist or is not a directory
		}else
		{
			h=0;
			v=v+1;
			labels.add(new Label("lblMarkerPieces","Marker pieces :",5,(30*v)+(10*(v+1))+30+20,200,20,true));
			v=v+1;
			for (int i=0; i<children.length; i++)
			{
				// Get filename of file or directory
				String filename = children[i];
				if(filename.contains(".marker"))
				{
					String uName = "";
					int k = 0;
					while(k<filename.length())
					{
						uName = uName + filename.charAt(k);
						k=k+1;
					}//loop
					uName = "markers/" + uName;
					File file = new File("./markers/" + filename);
					InputMessage IM = new InputMessage(ReadWriteTextFile.getContents(file),game);
					String ref = "";
					ref = IM.getUnitRef();
					images.add(new FormImage(uName,ref,game,(30*h)+(10*(h+1)),(30*v)+(10*(v+1))+30,30,30));
					FormImage fi = (FormImage)images.get(images.size()-1);
					fi.setOnBoard(false);
					h=h+1;
					if(h>=7)
					{
						h=0;
						v=v+1;
					}//if(h>=7)
				}//if(filename.contains(".unit"))
			}//next i
		}//else -- (children == null)
		
		dir = new File("./sprites/");
		children = dir.list();
		if (children == null)
		{
			// Either dir does not exist or is not a directory
		}else
		{
			h=0;
			v=v+1;
			labels.add(new Label("lblMiscPieces","Miscellaneous pieces :",5,(30*v)+(10*(v+1))+30+20,200,20,true));
			v=v+1;
			for (int i=0; i<children.length; i++)
			{
				// Get filename of file or directory
				String filename = children[i];
				if(filename.contains(".png"))
				{
					String uName = "";
					int k = 0;
					String ref = "sprites/";
					while(k<filename.length())
					{
						uName = uName + filename.charAt(k);
						ref = ref + filename.charAt(k);
						k=k+1;
					}//loop
					images.add(new FormImage(uName,ref,game,(30*h)+(10*(h+1)),(30*v)+(10*(v+1))+30,30,30));
					FormImage fi = (FormImage)images.get(images.size()-1);
					fi.setOnBoard(false);
					h=h+1;
					if(h>=7)
					{
						h=0;
						v=v+1;
					}//if(h>=7)
				}//if(filename.contains(".unit"))
			}//next i
		}//else -- (children == null)
		
		if(scrollBars.size()>0)
		{
			if(((images.size()/5)*30)>450)
			{
				ScrollBar s = (ScrollBar)scrollBars.get(0);
				s.setMaxValue(((images.size()/7)*30)-450);
			}else
			{
				ScrollBar s = (ScrollBar)scrollBars.get(0);
				s.setMaxValue(((images.size()/7)*30));
			}
		}
	}//updateContents()
	
	public void closingEvent()
	{
		game.setToolBox(null);
	}
	
	//GETTERS
	public boolean getDragging()
	{
		return dragging;
	}
	public IntValue getOffset()
	{
		return offset;
	}
	public int getOffsetValue()
	{
		return offset.getValue();
	}
	
	//SETTERS
	public void setDragging(boolean eDragging)
	{
		dragging=eDragging;
	}
	public void setOffset(IntValue eOffset)
	{
		offset = eOffset;
	}
	public void setOffset(int eOffset)
	{
		offset.setValue(eOffset);
	}
}//class ToolBox